package com.carrental.search.service.impl;

import com.carrental.common.result.Result;
import com.carrental.search.client.StoreClient;
import com.carrental.search.client.VehicleClient;
import com.carrental.search.model.document.VehicleDocument;
import com.carrental.search.repository.VehicleRepository;
import com.carrental.search.service.DataSyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 数据同步服务实现类
 */
@Slf4j
@Service
@ConditionalOnProperty(name = "spring.elasticsearch.repositories.enabled", havingValue = "true", matchIfMissing = true)
public class DataSyncServiceImpl implements DataSyncService {

    @Resource
    private VehicleClient vehicleClient;

    @Resource
    private StoreClient storeClient;

    @Resource
    private VehicleRepository vehicleRepository;

    @Override
    public int syncAllVehicles() {
        log.info("开始全量同步车辆数据到Elasticsearch");
        try {
            // 调用车辆微服务获取所有车辆数据
            Result<Map<String, Object>> result = vehicleClient.getAllVehicles();
            if (!result.isSuccess() || result.getData() == null) {
                log.error("获取车辆数据失败: {}", result.getMessage());
                return 0;
            }

            // 从分页结果中提取车辆列表
            Map<String, Object> pageData = result.getData();
            List<Map<String, Object>> vehicleList = null;
            
            // 处理分页返回的数据结构
            if (pageData.containsKey("records") && pageData.get("records") instanceof List) {
                vehicleList = (List<Map<String, Object>>) pageData.get("records");
            } else {
                log.error("无法从返回结果中获取车辆列表数据");
                return 0;
            }
            
            if (vehicleList == null || vehicleList.isEmpty()) {
                log.info("没有获取到车辆数据");
                return 0;
            }
            
            log.info("获取到{}条车辆数据", vehicleList.size());

            // 转换为VehicleDocument并保存
            List<VehicleDocument> vehicleDocuments = new ArrayList<>();
            for (Map<String, Object> vehicleMap : vehicleList) {
                VehicleDocument document = convertToVehicleDocument(vehicleMap);
                if (document != null) {
                    vehicleDocuments.add(document);
                }
            }

            if (!vehicleDocuments.isEmpty()) {
                vehicleRepository.saveAll(vehicleDocuments);
                log.info("成功同步{}条车辆数据到Elasticsearch", vehicleDocuments.size());
                return vehicleDocuments.size();
            }
            
            return 0;
        } catch (Exception e) {
            log.error("同步车辆数据到Elasticsearch失败", e);
            return 0;
        }
    }

    @Override
    public int syncIncrementalVehicles(Long lastSyncTime) {
        log.info("开始增量同步车辆数据到Elasticsearch, 上次同步时间: {}", lastSyncTime);
        try {
            // 调用车辆微服务的分页接口获取所有车辆数据
            Result<Map<String, Object>> result = vehicleClient.getAllVehicles();
            if (result.getCode() != 200) {
                log.error("获取车辆数据失败: {}", result.getMessage());
                return 0;
            }

            // 从分页结果中提取车辆列表
            Map<String, Object> pageData = result.getData();
            List<Map<String, Object>> vehicleList = null;
            
            // 处理分页返回的数据结构
            if (pageData.containsKey("records") && pageData.get("records") instanceof List) {
                vehicleList = (List<Map<String, Object>>) pageData.get("records");
            } else {
                log.error("无法从返回结果中获取车辆列表数据");
                return 0;
            }
            
            if (vehicleList == null || vehicleList.isEmpty()) {
                log.info("没有获取到车辆数据");
                return 0;
            }
            
            log.info("获取到{}条车辆数据", vehicleList.size());
            List<VehicleDocument> vehicleDocuments = new ArrayList<>();
            
            // 筛选出最近更新的车辆数据
            for (Map<String, Object> vehicleMap : vehicleList) {
                Object updateTimeObj = vehicleMap.get("createTime");
                if (updateTimeObj != null) {
                    Long updateTime = null;
                    if (updateTimeObj instanceof Long) {
                        updateTime = (Long) updateTimeObj;
                    } else if (updateTimeObj instanceof String) {
                        try {
                            updateTime = Long.parseLong((String) updateTimeObj);
                        } catch (NumberFormatException e) {
                            log.warn("无法解析更新时间: {}", updateTimeObj);
                        }
                    }
                    
                   // if (updateTime != null && updateTime > lastSyncTime) {
                        VehicleDocument document = convertToVehicleDocument(vehicleMap);
                        if (document != null) {
                            vehicleDocuments.add(document);
                    //    }
                    }
                }
            }

            if (!vehicleDocuments.isEmpty()) {
                vehicleRepository.saveAll(vehicleDocuments);
                log.info("成功增量同步{}条车辆数据到Elasticsearch", vehicleDocuments.size());
                return vehicleDocuments.size();
            }
            
            log.info("没有需要增量同步的车辆数据");
            return 0;
        } catch (Exception e) {
            log.error("增量同步车辆数据到Elasticsearch失败", e);
            return 0;
        }
    }

    @Override
    public boolean syncVehicle(Long vehicleId) {
        log.info("开始同步车辆数据, 车辆ID: {}", vehicleId);
        try {
            // 调用车辆微服务获取指定车辆数据
            Result<Map<String, Object>> result = vehicleClient.getVehicleDetail(vehicleId);
            if (!result.isSuccess() || result.getData() == null) {
                log.error("获取车辆数据失败, 车辆ID: {}, 错误: {}", vehicleId, result.getMessage());
                return false;
            }

            Map<String, Object> vehicleMap = result.getData();
            VehicleDocument document = convertToVehicleDocument(vehicleMap);
            
            if (document != null) {
                vehicleRepository.save(document);
                log.info("成功同步车辆数据到Elasticsearch, 车辆ID: {}", vehicleId);
                return true;
            }
            
            return false;
        } catch (Exception e) {
            log.error("同步车辆数据到Elasticsearch失败, 车辆ID: {}", vehicleId, e);
            return false;
        }
    }

    @Override
    public boolean deleteVehicle(Long vehicleId) {
        log.info("开始删除车辆索引数据, 车辆ID: {}", vehicleId);
        try {
            vehicleRepository.deleteById(vehicleId);
            log.info("成功删除车辆索引数据, 车辆ID: {}", vehicleId);
            return true;
        } catch (Exception e) {
            log.error("删除车辆索引数据失败, 车辆ID: {}", vehicleId, e);
            return false;
        }
    }

    @Override
    public int syncStoreLocations() {
        log.info("开始同步门店位置数据");
        try {
            // 调用门店微服务获取所有门店数据
            Result<List<Map<String, Object>>> result = storeClient.getAllStores();
            if (!result.isSuccess() || result.getData() == null) {
                log.error("获取门店数据失败: {}", result.getMessage());
                return 0;
            }

            List<Map<String, Object>> storeList = result.getData();
            log.info("获取到{}条门店数据", storeList.size());

            // 处理门店位置数据，更新相关车辆的门店信息
            // 这里简化处理，实际可能需要更复杂的逻辑
            int count = 0;
            for (Map<String, Object> storeMap : storeList) {
                Long storeId = getLongValue(storeMap, "id");
                String storeName = (String) storeMap.get("name");
                Double latitude = getDoubleValue(storeMap, "latitude");
                Double longitude = getDoubleValue(storeMap, "longitude");
                
                if (storeId != null && latitude != null && longitude != null) {
                    // 获取该门店的所有车辆
                    Result<Map<String, Object>> vehiclesResult = vehicleClient.getVehiclesByStore(storeId);
                    if (vehiclesResult.isSuccess() && vehiclesResult.getData() != null) {
                        Map<String, Object> pageData = vehiclesResult.getData();
                        List<Map<String, Object>> storeVehicles = null;
                        
                        // 处理分页返回的数据结构
                        if (pageData.containsKey("records") && pageData.get("records") instanceof List) {
                            storeVehicles = (List<Map<String, Object>>) pageData.get("records");
                        } else {
                            log.warn("无法从返回结果中获取门店{}的车辆列表数据", storeId);
                            continue;
                        }
                        
                        if (storeVehicles == null || storeVehicles.isEmpty()) {
                            log.info("门店{}没有车辆数据", storeId);
                            continue;
                        }
                        
                        for (Map<String, Object> vehicleMap : storeVehicles) {
                            Long vehicleId = getLongValue(vehicleMap, "id");
                            if (vehicleId != null) {
                                // 更新车辆的门店和位置信息
                                VehicleDocument vehicleDocument = vehicleRepository.findById(vehicleId).orElse(null);
                                if (vehicleDocument != null) {
                                    vehicleDocument.setStoreId(storeId);
                                    vehicleDocument.setStoreName(storeName);
                                    vehicleDocument.setLocation(new GeoPoint(latitude, longitude));
                                    vehicleRepository.save(vehicleDocument);
                                    count++;
                                }
                            }
                        }
                    }
                }
            }
            
            log.info("成功同步{}条车辆的门店位置数据", count);
            return count;
        } catch (Exception e) {
            log.error("同步门店位置数据失败", e);
            return 0;
        }
    }

    /**
     * 将车辆Map转换为VehicleDocument
     *
     * @param vehicleMap 车辆Map
     * @return VehicleDocument
     */
    private VehicleDocument convertToVehicleDocument(Map<String, Object> vehicleMap) {
        try {
            VehicleDocument document = new VehicleDocument();
            
            document.setId(getLongValue(vehicleMap, "id"));
            document.setName((String) vehicleMap.get("name"));
            document.setBrand((String) vehicleMap.get("brand"));
            document.setModel((String) vehicleMap.get("model"));
           // document.setType((String) vehicleMap.get("type"));
            document.setColor((String) vehicleMap.get("color"));
            document.setPlateNumber((String) vehicleMap.get("plateNumber"));
            document.setSeats(getIntegerValue(vehicleMap, "seats"));
            document.setEngineType((String) vehicleMap.get("engineType"));
         //   document.setTransmissionType((String) vehicleMap.get("transmissionType"));
          //  document.setFuelType((String) vehicleMap.get("fuelType"));
            document.setDailyRent(getBigDecimalValue(vehicleMap, "dailyRent"));
            document.setStatus(getIntegerValue(vehicleMap, "status"));

            // 处理图片列表
            Object imagesObj = vehicleMap.get("images");
            if (imagesObj instanceof List) {
                document.setImages((List<String>) imagesObj);
            }

            document.setStoreId(getLongValue(vehicleMap, "storeId"));
            document.setStoreName((String) vehicleMap.get("storeName"));
            
            // 处理位置信息
            Double latitude = getDoubleValue(vehicleMap, "latitude");
            Double longitude = getDoubleValue(vehicleMap, "longitude");
            if (latitude != null && longitude != null) {
                document.setLocation(new GeoPoint(latitude, longitude));
            } else if (document.getStoreId() != null) {
                // 如果车辆本身没有位置信息，尝试从门店获取
               // Result<Map<String, Object>> storeResult = storeClient.getStoreDetail(document.getStoreId());
//                if (storeResult.isSuccess() && storeResult.getData() != null) {
//                    Map<String, Object> storeMap = storeResult.getData();
//                    latitude = getDoubleValue(storeMap, "latitude");
//                    longitude = getDoubleValue(storeMap, "longitude");
//                    if (latitude != null && longitude != null) {
//                        document.setLocation(new GeoPoint(latitude, longitude));
//                    }
//                }
            }

            document.setDescription((String) vehicleMap.get("description"));
            
            // 处理特性列表
            Object featuresObj = vehicleMap.get("features");
            if (featuresObj instanceof List) {
                document.setFeatures((List<String>) featuresObj);
            }

//            document.setYear(getIntegerValue(vehicleMap, "year"));
//            document.setMileage(getDoubleValue(vehicleMap, "mileage"));
//            document.setRating(getFloatValue(vehicleMap, "rating"));
//            document.setRatingCount(getIntegerValue(vehicleMap, "ratingCount"));
//            document.setRentalCount(getIntegerValue(vehicleMap, "rentalCount"));
//            document.setRecommended(getBooleanValue(vehicleMap, "recommended"));
//            document.setCreateTime(getLongValue(vehicleMap, "createTime"));
//            document.setUpdateTime(getLongValue(vehicleMap, "updateTime"));

            return document;
        } catch (Exception e) {
            log.error("转换车辆数据失败", e);
            return null;
        }
    }

    /**
     * 从Map中获取Long值
     */
    private long getLongValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return 1;
        }
        if (value instanceof Long) {
            return (long) value;
        }
        if (value instanceof Integer) {
            return ((Integer) value).longValue();
        }
        if (value instanceof String) {
            try {
                return Long.parseLong((String) value);
            } catch (NumberFormatException e) {
                return 1;
            }
        }
        return 1;
    }

    /**
     * 从Map中获取Integer值
     */
    private Integer getIntegerValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Integer) {
            return (Integer) value;
        }
        if (value instanceof Long) {
            return ((Long) value).intValue();
        }
        if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 从Map中获取Double值
     */
    private Double getDoubleValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Double) {
            return (Double) value;
        }
        if (value instanceof Float) {
            return ((Float) value).doubleValue();
        }
        if (value instanceof Integer) {
            return ((Integer) value).doubleValue();
        }
        if (value instanceof Long) {
            return ((Long) value).doubleValue();
        }
        if (value instanceof String) {
            try {
                return Double.parseDouble((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 从Map中获取Float值
     */
    private Float getFloatValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Float) {
            return (Float) value;
        }
        if (value instanceof Double) {
            return ((Double) value).floatValue();
        }
        if (value instanceof Integer) {
            return ((Integer) value).floatValue();
        }
        if (value instanceof Long) {
            return ((Long) value).floatValue();
        }
        if (value instanceof String) {
            try {
                return Float.parseFloat((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 从Map中获取BigDecimal值
     */
    private BigDecimal getBigDecimalValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        if (value instanceof Double) {
            return BigDecimal.valueOf((Double) value);
        }
        if (value instanceof Float) {
            return BigDecimal.valueOf((Float) value);
        }
        if (value instanceof Integer) {
            return BigDecimal.valueOf((Integer) value);
        }
        if (value instanceof Long) {
            return BigDecimal.valueOf((Long) value);
        }
        if (value instanceof String) {
            try {
                return new BigDecimal((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 从Map中获取Boolean值
     */
    private Boolean getBooleanValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Boolean) {
            return (Boolean) value;
        }
        if (value instanceof String) {
            return Boolean.parseBoolean((String) value);
        }
        if (value instanceof Integer) {
            return ((Integer) value) != 0;
        }
        return null;
    }
}